
package cn.sj.cordova.bluetoothprint;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.apache.commons.lang.ArrayUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.json.JSONException;

import java.util.Iterator;
import java.util.Vector;
import java.util.ArrayList;
import java.util.logging.Logger;
import java.util.Set;


import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.Toast;
import android.util.Base64;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.Toast;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
// import android.content.ServiceConnection;
// import android.content.ComponentName;
// import android.content.Context;
// import android.content.Intent;
// import android.os.Bundle;
// import android.os.IBinder;
import android.content.*;
// import android.content.ContextWrapper;
import android.os.*;
// import android.os.RemoteException;
import android.app.Activity;
import android.view.*;
// import android.view.ContextThemeWrapper;

import com.gprinter.aidl.GpService;
import com.gprinter.io.GpDevice;

import com.gprinter.service.GpPrintService;
import com.gprinter.command.GpCom;
import com.gprinter.io.PortParameters;
import com.gprinter.save.PortParamDataBase;
import com.gprinter.service.GpPrintService;
import com.gprinter.command.TscCommand;
import com.gprinter.command.EscCommand;
import com.gprinter.command.EscCommand.ENABLE;
import com.gprinter.command.EscCommand.FONT;
import com.gprinter.command.EscCommand.HRI_POSITION;
import com.gprinter.command.EscCommand.JUSTIFICATION;
import com.gprinter.command.TscCommand.BARCODETYPE;
import com.gprinter.command.TscCommand.BITMAP_MODE;
import com.gprinter.command.TscCommand.DIRECTION;
import com.gprinter.command.TscCommand.EEC;
import com.gprinter.command.TscCommand.FONTMUL;
import com.gprinter.command.TscCommand.FONTTYPE;
import com.gprinter.command.TscCommand.MIRROR;
import com.gprinter.command.TscCommand.READABEL;
import com.gprinter.command.TscCommand.ROTATION;
import com.yonyouwl.scanPrint.R;



public class BluetoothPrintPlugin extends CordovaPlugin {

    private BluetoothAdapter mBluetoothAdapter;
    private PrinterServiceConnection conn = null;
    private GpService mGpService = null;
    private Activity activity;
    private String name = "" ;
    private String car = "";
    private String wish = "";
    private String position = "";
    private String orderDate = "";
    private String orderNo = "";
    
    

    @Override
    public void initialize(CordovaInterface cordova, CordovaWebView webView) {
        super.initialize(cordova, webView);
        
        activity = cordova.getActivity();
        connection();//缁戝畾鏈嶅姟
        registerBroadcast();//娉ㄥ唽杩炴帴鐘舵�骞挎挱
        registerBoothCloseBroadcast();//娉ㄥ唽钃濈墮鍏抽棴骞挎挱
    }

    private void registerBoothCloseBroadcast() {
        //step1ע��㲥
        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED);//�����Ͽ�
        activity.getApplicationContext().registerReceiver(mBluetoothReceiver, filter);
    }

    //step2 �����㲥
    private final BroadcastReceiver mBluetoothReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            // �Ͽ�����
            if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {

                try {
                    mGpService.closePort(0);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
            if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {

                try {
                    mGpService.closePort(0);
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }
        }
    };

    private void registerBroadcast() {
        IntentFilter filter = new IntentFilter();
        filter.addAction(GpCom.ACTION_CONNECT_STATUS);
        activity.getApplicationContext().registerReceiver(PrinterStatusBroadcastReceiver, filter);
    }

    private BroadcastReceiver PrinterStatusBroadcastReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (GpCom.ACTION_CONNECT_STATUS.equals(intent.getAction())) {
                int type = intent.getIntExtra(GpPrintService.CONNECT_STATUS, 0);
                int id = intent.getIntExtra(GpPrintService.PRINTER_ID, 0);
                

                // if (type == GpDevice.STATE_CONNECTING) {//2 连接中
                    
                // } else if (type == GpDevice.STATE_NONE) {//0 断开（断开成功）
                    
                // } else if (type == GpDevice.STATE_VALID_PRINTER) {//5 打印机可用（连接成功）
                    
                // } else if (type == GpDevice.STATE_INVALID_PRINTER) {//4 打印机不可用
                    
                // }
                String jsEvent = String.format(
                "cordova.fireDocumentEvent('bluetoothprint.StatusReceived',{'bluetoothPrintStatus':'%s'})",
                type);
                webView.sendJavascript(jsEvent);  
            }
        }
    };

    class PrinterServiceConnection implements ServiceConnection {
        @Override
        public void onServiceDisconnected(ComponentName name) {
            
            mGpService = null;
        }

        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            mGpService = GpService.Stub.asInterface(service);
        }
    }

    private void connection() {
        conn = new PrinterServiceConnection();
        Intent intent = new Intent("com.gprinter.aidl.GpPrintService");
        activity.getApplicationContext().bindService(intent, conn, Context.BIND_AUTO_CREATE); // bindService
    }
     
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
        //获取已配对的蓝牙设备
        if (action.equals("getPairedDevices")) {
            getPairedDevices();
            return true;
        }
        //连接选中的蓝牙设备(打印机)
        if (action.equals("connectDevice")){
            connectDevice(args, callbackContext);
            return true;
        }
        //打印
        if (action.equals("printText")){
            printText(args, callbackContext);
            return true;
        }
        //关闭连接
        if (action.equals("closeConnect")){
             try {
                mGpService.closePort(0);
             } catch (RemoteException e) {
                e.printStackTrace();
             }
            return true;
        }
        
        return false;
    }

    private void connectDevice(final JSONArray args, final CallbackContext callbackContext) throws JSONException {
        final String address = args.getString(0);
        // name = args.getString(1);
        // car = args.getString(2);
        // wish = args.getString(3);
        // position = args.getString(4);
        // orderNo = args.getString(5);
        // orderDate = args.getString(6);
        
        Toast.makeText(activity.getApplicationContext(), address,
        Toast.LENGTH_SHORT).show();
        
        //已经连接
        // try {
        //     if (mGpService.getPrinterConnectStatus(0) == GpDevice.STATE_CONNECTED) {
            
        //     }
        //     //未连接
        //     else{
               if(!address.equals("")&&!address.equals("null")&&address!=null){
                     int rel = 0;
                     try {
                        mGpService.closePort(0);
                     } catch (RemoteException e) {
                        e.printStackTrace();
                     }
                     try {
                        //打印机id，连接类型（蓝牙4），蓝牙地址，0
                        rel = mGpService.openPort(0, 4, address, 0);
                     } catch (RemoteException e) {
                        e.printStackTrace();
                     }
                     // GpCom.ERROR_CODE r = GpCom.ERROR_CODE.values()[rel];
                     // if (r == GpCom.ERROR_CODE.SUCCESS) {
                     //    callbackContext.success("连接成功");
                     // }
                     // else{
                     //    callbackContext.success("连接失败");
                     // }
                }
            // }
        // } catch (RemoteException e) {
        //     // TODO Auto-generated catch block
        //     e.printStackTrace();
        // }
        
    }

    private void getPairedDevices(){

        // Get the local Bluetooth adapter
        mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        // Get a set of currently paired devices
        Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
        // If there are paired devices, add each one to the ArrayAdapter
        if (pairedDevices.size() > 0) {
            String str = "";
            for (BluetoothDevice device : pairedDevices) {
                
                str+= device.getName() + "&"+ device.getAddress() +",";
                
                
            }
            String jsEvent = String.format(
                "cordova.fireDocumentEvent('bluetoothprint.DataReceived',{'bluetoothPrintData':'%s'})",
                str);
            webView.sendJavascript(jsEvent);                     
        }

    }

    private void printText(final JSONArray args, final CallbackContext callbackContext) throws JSONException{
        name = args.getString(0);
        car = args.getString(1);
        wish = args.getString(2);
        position = args.getString(3);
        orderNo = args.getString(4);
        orderDate = args.getString(5);

        setPrintData();

    }

    private void setPrintData(){

        TscCommand tsc = new TscCommand(); 
        tsc.addSize(40, 30); //设置标签尺寸，按照实际尺寸设置 
        tsc.addGap(2); //设置标签间隙，按照实际尺寸设置，如果为无间隙纸则设置为0
        tsc.addDirection(DIRECTION.BACKWARD,MIRROR.NORMAL);//设置打印方向 
        tsc.addReference(0, 0);//设置原点坐标 
        tsc.addTear(ENABLE.ON); //撕纸模式开启 
        tsc.addCls();// 清除打印缓冲区 
        //绘制图片
        Bitmap b = BitmapFactory.decodeResource(activity.getApplicationContext().getResources(),
                R.drawable.logo);
        tsc.addBitmap(220, 15, BITMAP_MODE.OVERWRITE, b.getWidth()/7, b);
        //绘制简体中文 
        tsc.addText(0,60,FONTTYPE.SIMPLIFIED_CHINESE,ROTATION.ROTATION_0,FONTMUL.MUL_1,FONTMUL.MUL_1,"品名："+car);
        tsc.addText(0,85,FONTTYPE.SIMPLIFIED_CHINESE,ROTATION.ROTATION_0,FONTMUL.MUL_1,FONTMUL.MUL_1,"订单号："+orderNo);
        tsc.addText(0,110,FONTTYPE.SIMPLIFIED_CHINESE,ROTATION.ROTATION_0,FONTMUL.MUL_1,FONTMUL.MUL_1,"客户："+name);
        tsc.addText(0,135,FONTTYPE.SIMPLIFIED_CHINESE,ROTATION.ROTATION_0,FONTMUL.MUL_1,FONTMUL.MUL_1,"取货口："+position);
        tsc.addText(0,160,FONTTYPE.SIMPLIFIED_CHINESE,ROTATION.ROTATION_0,FONTMUL.MUL_1,FONTMUL.MUL_1,"祝福语："+wish);
        tsc.addText(0,185,FONTTYPE.SIMPLIFIED_CHINESE,ROTATION.ROTATION_0,FONTMUL.MUL_1,FONTMUL.MUL_1,"生产时间：");
        
        tsc.addText(0,210,FONTTYPE.SIMPLIFIED_CHINESE,ROTATION.ROTATION_0,FONTMUL.MUL_1,FONTMUL.MUL_1,orderDate);
        

        // tsc.addText("品名：吉普车\n");
        // tsc.addText("订单号：os1234567\n");
        // tsc.addText("客户：微信号\n");
        // tsc.addText("取货口：北京\n");
        // tsc.addText("祝福语：亲亲我的宝贝\n");
        // tsc.addText("生产厂家：用友年会体验区智能工厂\n");
        // tsc.addText("生产时间：完工时间\n");
        tsc.addPrint(1,1); // 打印标签 
        tsc.addSound(2, 100); //打印标签后 蜂鸣器响 
        Vector<Byte> datas = tsc.getCommand(); //发送数据 
        Byte[] Bytes = datas.toArray(new Byte[datas.size()]); 
        byte[] bytes = ArrayUtils.toPrimitive(Bytes); 
        String str = Base64.encodeToString(bytes, Base64.DEFAULT); 
        int rel; 
        try { 
            rel = mGpService.sendTscCommand(0, str); 
            // GpCom.ERROR_CODE r=GpCom.ERROR_CODE.values()[rel]; 
            // if(r != GpCom.ERROR_CODE.SUCCESS){ 
            //    Toast.makeText(getApplicationContext(),GpCom.getErrorText(r), Toast.LENGTH_SHORT).show(); 
            // } 
        } 
        catch (RemoteException e) { // TODO Auto-generated catch block
            e.printStackTrace();
        }


    }
    // public void onDataReceived(final String port, final String input) {
    //     try {
    //         cordova.getActivity().runOnUiThread(new Runnable() {
    //             public void run() {
    //                 String jsEvent = String.format(
    //                         "cordova.fireDocumentEvent('serialport.DataReceived',{'serialPort':'%s','serialPortData':'%s'})",
    //                         port, input);
    //                 webView.sendJavascript(jsEvent);
    //             }
    //         });
    //     } catch (Exception e) {
    //         e.printStackTrace();
    //     }
    // }

    @Override
    public void onDestroy() {
        super.onDestroy();
         try {
            mGpService.closePort(0);
         } catch (RemoteException e) {
            e.printStackTrace();
         }
    }
}